package com.demo.service.impl;


import com.demo.dao.OrderMapper;
import com.demo.dao.ProductMapper;
import com.demo.domain.Order;
import com.demo.domain.Product;
import com.demo.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Copyright
 *
 * @Author WuHuang
 * @Date 2022/6/10
 */
@Service
public class OrderServiceImpl implements OrderService {

    //错误的展示,在一个方法里边获取锁，在高并发情况下订单会超库存，
    //因为 请求A抢到锁创建订单事务还没有进行提交,小各请求B会进来发现
    //库存还有会再次创建订单
    @Resource
    private ProductMapper productMapper;

    @Resource
    private OrderMapper orderMapper;

    private Lock lock = new ReentrantLock(true);

    @Override
    @Transactional
    public void saveOrder() {

        try {
            if (!lock.tryLock()) {
                return;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + ":抢到锁，进入方法");
        Product product = productMapper.selectById(1);
        Integer productCount = product.getProductCount();
        System.out.println(Thread.currentThread().getName() + "当前库存：" + productCount);
        if (productCount > 0) {
            Product build = Product.builder()
                    .id(product.getId())
                    .name(product.getName())
                    .productCount(productCount - 1)
                    .build();
            productMapper.updateById(build);

            Order order = Order.builder()
                    .userName(Thread.currentThread().getName())
                    .goodsName(product.getName() == null ? "默认" : product.getName())
                    .build();

            orderMapper.insert(order);

            System.out.println(Thread.currentThread().getName() + ":减少库存，创建订单完成");
        } else {
            System.out.println(Thread.currentThread().getName() + ":没有库存了   ");
        }
        lock.unlock();
    }

    @Override
    public void saveOrderV2() {
//        RLock lock = redissonClient.getLock("test:demo:");
            try {
//            if (!lock.tryLock( 1,30, TimeUnit.MINUTES)) {
//                return;
//            }
                if (!lock.tryLock()) {
                    return;
                }
                saveOrder();
                lock.unlock();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
}
